/**
 * XDevice - 高可靠分布式存储库
 * 
 * 提供类POSIX接口，隐藏分布式实现细节，
 * 为应用程序提供透明的跨节点数据可靠性保障。
 */

#ifndef LIBXDEVICE_H
#define LIBXDEVICE_H

#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include <time.h>

#ifdef __cplusplus
extern "C" {
#endif

/* 版本信息 */
#define XDEVICE_VERSION "1.0.0"

/* 文件描述符类型 */
typedef int xdevice_fd_t;

/* 错误码 - 遵循POSIX风格 */
#define XDEVICE_OK           0
#define XDEVICE_ERROR       -1
#define XDEVICE_ENOENT      -2    /* 文件不存在 */
#define XDEVICE_EEXIST      -3    /* 文件已存在 */
#define XDEVICE_EACCES      -4    /* 权限错误 */
#define XDEVICE_EIO         -5    /* I/O错误 */
#define XDEVICE_ENOMEM      -6    /* 内存不足 */
#define XDEVICE_EINVAL      -7    /* 无效参数 */
#define XDEVICE_ENOSPC      -8    /* 空间不足 */
#define XDEVICE_ETIMEDOUT   -9    /* 超时 */
#define XDEVICE_ENOTREADY  -10    /* 系统未就绪 */

/* 打开模式 - 类似POSIX */
#define XDEVICE_O_RDONLY    0x01
#define XDEVICE_O_WRONLY    0x02
#define XDEVICE_O_RDWR      0x03
#define XDEVICE_O_CREAT     0x04
#define XDEVICE_O_EXCL      0x08
#define XDEVICE_O_TRUNC     0x10
#define XDEVICE_O_SYNC      0x20

/* 一致性级别 - 基于Raft的一致性保证 */
#define XDEVICE_CONSISTENCY_EVENTUAL    0x100   /* 最终一致性，读本地副本 */
#define XDEVICE_CONSISTENCY_STRONG      0x200   /* 强一致性，读Leader */
#define XDEVICE_CONSISTENCY_QUORUM      0x400   /* 仲裁读，多数派确认 */

/* 写入策略 - 控制Raft日志同步行为 */
#define XDEVICE_WRITE_ASYNC            0x1000   /* 异步写入，提交到Leader即返回 */
#define XDEVICE_WRITE_SYNC             0x2000   /* 同步写入，等待多数派确认 */
#define XDEVICE_WRITE_FSYNC            0x4000   /* 强制同步，等待所有副本确认 */

/* 文件属性结构 - 类似stat */
typedef struct xdevice_stat {
    char name[256];           /* 设备名称 */
    uint64_t size;            /* 设备大小 */
    uint64_t blocks;          /* 块数量 */
    uint32_t blksize;         /* 块大小 */
    time_t ctime;             /* 创建时间 */
    time_t mtime;             /* 修改时间 */
    time_t atime;             /* 访问时间 */
    mode_t mode;              /* 权限模式 */
    int replicas;             /* 副本数量 */
    int healthy_replicas;     /* 健康副本数 */
} xdevice_stat_t;

/* 库健康状态信息 */
typedef struct xdevice_health {
    int is_healthy;           /* 整体健康状态 */
    int total_nodes;          /* 总节点数 */
    int active_nodes;         /* 活跃节点数 */
    int has_leader;           /* 是否有领导者 */
    float availability;       /* 可用性百分比 */
    char leader_node[64];     /* 当前Leader节点ID */
    uint64_t raft_term;       /* 当前Raft任期 */
    uint64_t raft_index;      /* 当前Raft日志索引 */
} xdevice_health_t;

/* Raft集群状态信息 */
typedef struct xdevice_raft_status {
    char node_id[64];         /* 当前节点ID */
    int role;                 /* 节点角色: 0=Follower, 1=Candidate, 2=Leader */
    uint64_t current_term;    /* 当前任期 */
    uint64_t commit_index;    /* 已提交的日志索引 */
    uint64_t last_applied;    /* 已应用的日志索引 */
    char leader_id[64];       /* Leader节点ID */
    int votes_received;       /* 获得的选票数 */
    int election_timeout_ms;  /* 选举超时时间 */
} xdevice_raft_status_t;

/* 设备副本状态信息 */
typedef struct xdevice_replica_info {
    char node_id[64];         /* 副本所在节点 */
    int is_healthy;           /* 副本健康状态 */
    uint64_t last_sync_index; /* 最后同步的日志索引 */
    int lag_ms;               /* 同步延迟(毫秒) */
    int is_in_sync;           /* 是否与Leader同步 */
} xdevice_replica_info_t;

/* ========== 核心API函数 ========== */

/**
 * 初始化XDevice库 - 应用启动时调用一次
 * 
 * 此函数会：
 * 1. 读取配置文件，获取集群节点信息
 * 2. 连接到分布式集群，进行节点发现和认证
 * 3. 同步设备命名空间，获取所有可用的逻辑设备列表
 * 4. 初始化Raft协议栈和存储引擎
 * 5. 启动健康检查和故障检测机制
 * 
 * 配置文件格式示例 (/etc/xdevice/cluster.conf):
 * ```
 * [cluster]
 * nodes = node1:8080,node2:8080,node3:8080
 * replica_count = 3
 * 
 * [devices]
 * database = size:10GB,replicas:3
 * logs = size:1GB,replicas:2  
 * cache = size:2GB,replicas:1
 * ```
 * 
 * @param config_path 配置文件路径，NULL使用默认配置(/etc/xdevice/cluster.conf)
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   // 使用指定配置文件
 *   if (xdevice_init("/etc/myapp/xdevice.conf") != XDEVICE_OK) {
 *       fprintf(stderr, "Failed to initialize XDevice\n");
 *       exit(1);
 *   }
 *   
 *   // 使用默认配置
 *   xdevice_init(NULL);
 */
int lx_init(const char* config_path);

/**
 * 清理XDevice库 - 应用退出时调用
 * 
 * 示例:
 *   xdevice_cleanup();
 */
void lx_cleanup(void);

/**
 * 打开/创建设备 - 类似open()，支持Raft一致性控制
 * 
 * 设备操作流程：
 * 1. 如果设备已存在：直接打开并返回文件描述符
 * 2. 如果设备不存在且指定CREAT：通过Raft协议在集群中创建新设备
 * 3. 如果设备不存在且未指定CREAT：返回XDEVICE_ENOENT错误
 * 
 * Raft一致性控制：
 * - 设备创建需要通过Raft日志达成集群共识
 * - 可以指定一致性级别控制读取行为
 * - 可以指定写入策略控制Raft同步行为
 * 
 * @param device_name 设备名称(不是路径，而是逻辑设备名)
 * @param flags 打开标志，支持：
 *              - 基础标志: XDEVICE_O_RDONLY, XDEVICE_O_WRONLY, XDEVICE_O_RDWR
 *              - 创建标志: XDEVICE_O_CREAT, XDEVICE_O_EXCL, XDEVICE_O_TRUNC
 *              - 一致性级别: XDEVICE_CONSISTENCY_*
 *              - 写入策略: XDEVICE_WRITE_*
 * @param size 设备大小(仅在创建时使用，字节)
 * @return 设备文件描述符，失败返回负数错误码
 * 
 * 示例:
 *   // 打开设备，强一致性读取
 *   xdevice_fd_t fd = xdevice_open("database", 
 *       XDEVICE_O_RDWR | XDEVICE_CONSISTENCY_STRONG, 0);
 *   
 *   // 创建设备，异步写入（高性能）
 *   xdevice_fd_t fd = xdevice_open("logs", 
 *       XDEVICE_O_CREAT | XDEVICE_O_RDWR | XDEVICE_WRITE_ASYNC, 1024*1024*1024);
 *   
 *   // 创建设备，强制同步写入（高可靠）
 *   xdevice_fd_t fd = xdevice_open("critical_data",
 *       XDEVICE_O_CREAT | XDEVICE_O_RDWR | XDEVICE_WRITE_FSYNC, 512*1024*1024);
 */
xdevice_fd_t lx_open(const char* device_name, int flags, uint64_t size);

/**
 * 关闭设备 - 类似close()
 * 
 * @param fd 设备文件描述符
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   xdevice_close(fd);
 */
int lx_close(xdevice_fd_t fd);

/**
 * 写入数据 - 类似pwrite()，支持Raft一致性控制
 * 
 * 数据写入流程：
 * 1. 数据写入请求首先发送到Raft Leader节点
 * 2. Leader将写入操作作为日志条目追加到Raft日志
 * 3. 根据写入策略决定同步行为：
 *    - ASYNC: Leader接收后立即返回
 *    - SYNC: 等待多数派Follower确认后返回
 *    - FSYNC: 等待所有活跃副本确认后返回
 * 4. 一旦日志被提交，数据自动复制到所有副本节点
 * 
 * @param fd 设备文件描述符
 * @param buf 写入缓冲区
 * @param count 写入字节数
 * @param offset 设备偏移量
 * @return 实际写入字节数，失败返回负数错误码
 * 
 * 错误处理：
 * - XDEVICE_ETIMEDOUT: Raft同步超时
 * - XDEVICE_ENOTREADY: 集群无Leader或分区
 * - XDEVICE_EIO: 副本写入失败
 * 
 * 示例:
 *   const char* data = "Hello, XDevice!";
 *   ssize_t bytes = xdevice_pwrite(fd, data, strlen(data), 0);
 *   if (bytes < 0 && bytes == XDEVICE_ETIMEDOUT) {
 *       // 处理Raft同步超时
 *   }
 */
ssize_t lx_pwrite(xdevice_fd_t fd, const void* buf, size_t count, off_t offset);

/**
 * 读取数据 - 类似pread()，支持一致性级别控制
 * 
 * 数据读取流程：
 * 1. 根据打开时指定的一致性级别决定读取策略：
 *    - EVENTUAL: 从本地副本读取（最快，可能读到旧数据）
 *    - STRONG: 从Leader读取（保证读到最新数据）
 *    - QUORUM: 从多数派读取（平衡性能和一致性）
 * 2. 如果本地副本不可用，自动从其他节点读取
 * 3. 支持故障自动切换和重试
 * 
 * @param fd 设备文件描述符
 * @param buf 读取缓冲区
 * @param count 读取字节数
 * @param offset 设备偏移量
 * @return 实际读取字节数，失败返回负数错误码
 * 
 * 示例:
 *   char buffer[4096];
 *   ssize_t bytes = xdevice_pread(fd, buffer, sizeof(buffer), 0);
 */
ssize_t lx_pread(xdevice_fd_t fd, void* buf, size_t count, off_t offset);

/**
 * 顺序读取数据 - 类似read()，维护文件位置指针
 * 
 * @param fd 设备文件描述符
 * @param buf 读取缓冲区
 * @param count 读取字节数
 * @return 实际读取字节数，失败返回负数错误码
 * 
 * 示例:
 *   char buffer[4096];
 *   ssize_t bytes = xdevice_read(fd, buffer, sizeof(buffer));
 */
ssize_t lx_read(xdevice_fd_t fd, void* buf, size_t count);

/**
 * 顺序写入数据 - 类似write()，维护文件位置指针
 * 
 * @param fd 设备文件描述符
 * @param buf 写入缓冲区
 * @param count 写入字节数
 * @return 实际写入字节数，失败返回负数错误码
 * 
 * 示例:
 *   const char* data = "Hello, XDevice!";
 *   ssize_t bytes = xdevice_write(fd, data, strlen(data));
 */
ssize_t lx_write(xdevice_fd_t fd, const void* buf, size_t count);

/**
 * 移动文件位置指针 - 类似lseek()
 * 
 * @param fd 设备文件描述符
 * @param offset 偏移量
 * @param whence 定位方式 (SEEK_SET, SEEK_CUR, SEEK_END)
 * @return 新的文件位置，失败返回负数错误码
 * 
 * 示例:
 *   off_t pos = xdevice_lseek(fd, 0, SEEK_END);  // 移动到文件末尾
 *   xdevice_lseek(fd, 0, SEEK_SET);              // 移动到文件开头
 */
off_t lx_lseek(xdevice_fd_t fd, off_t offset, int whence);

/**
 * 同步数据到存储 - 类似fsync()
 * 
 * 确保数据已持久化到足够数量的副本
 * 
 * @param fd 设备文件描述符
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   xdevice_fsync(fd);  // 确保数据持久化
 */
int lx_fsync(xdevice_fd_t fd);

/**
 * 获取设备属性 - 类似fstat()
 * 
 * @param fd 设备文件描述符
 * @param stat 设备属性结构
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   xdevice_stat_t stat;
 *   if (xdevice_fstat(fd, &stat) == XDEVICE_OK) {
 *       printf("Device size: %lu bytes, replicas: %d\n", 
 *              stat.size, stat.replicas);
 *   }
 */
int lx_fstat(xdevice_fd_t fd, xdevice_stat_t* stat);

/**
 * 删除设备 - 类似unlink()
 * 
 * @param device_name 设备名称
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   xdevice_unlink("temp_cache");
 */
int lx_unlink(const char* device_name);

/**
 * 重命名设备 - 类似rename()
 * 
 * @param old_name 原设备名称
 * @param new_name 新设备名称
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   xdevice_rename("temp_database", "production_database");
 */
int lx_rename(const char* old_name, const char* new_name);

/* ========== 扩展API（辅助功能） ========== */

/**
 * 获取错误描述字符串 - 类似strerror()
 * 
 * @param errnum 错误码
 * @return 错误描述字符串
 * 
 * 示例:
 *   int ret = xdevice_open("invalid_device", XDEVICE_O_RDONLY, 0);
 *   if (ret < 0) {
 *       fprintf(stderr, "Error: %s\n", xdevice_strerror(ret));
 *   }
 */
const char* lx_strerror(int errnum);

/**
 * 检查库健康状态
 * 
 * @param health 健康状态信息(可为NULL)
 * @return 1健康，0不健康，负数表示错误
 * 
 * 示例:
 *   xdevice_health_t health;
 *   if (xdevice_health_check(&health)) {
 *       printf("Cluster healthy: %d/%d nodes active\n", 
 *              health.active_nodes, health.total_nodes);
 *   }
 */
int lx_health_check(xdevice_health_t* health);

/**
 * 获取库版本信息
 * 
 * @return 版本字符串
 * 
 * 示例:
 *   printf("XDevice version: %s\n", xdevice_version());
 */
const char* lx_version(void);

/**
 * 列出所有设备
 * 
 * 返回集群中所有可用的设备列表，包括：
 * - 配置文件中预定义的设备
 * - 运行时动态创建的设备
 * - 其他节点创建的共享设备
 * 
 * @param device_names 设备名称数组
 * @param max_count 最大设备数
 * @return 实际设备数，失败返回负数错误码
 * 
 * 示例:
 *   char devices[100][256];
 *   int count = xdevice_list_devices(devices, 100);
 *   for (int i = 0; i < count; i++) {
 *       printf("Device: %s\n", devices[i]);
 *   }
 */
int lx_list_devices(char device_names[][256], int max_count);

/**
 * 检查设备是否存在
 * 
 * 快速检查指定的逻辑设备是否在集群中存在，
 * 避免使用open()进行存在性检查的开销。
 * 
 * @param device_name 设备名称
 * @return 1存在，0不存在，负数表示错误码
 * 
 * 示例:
 *   if (xdevice_exists("database")) {
 *       printf("Database device is available\n");
 *   } else {
 *       printf("Database device needs to be created\n");
 *   }
 */
int lx_exists(const char* device_name);

/**
 * 获取设备信息（无需打开设备）
 * 
 * 获取设备的基本信息而不需要打开设备文件描述符，
 * 适用于设备管理和监控场景。
 * 
 * @param device_name 设备名称
 * @param stat 设备属性结构
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   xdevice_stat_t stat;
 *   if (xdevice_stat("database", &stat) == XDEVICE_OK) {
 *       printf("Device: %s, Size: %lu, Replicas: %d\n",
 *              stat.name, stat.size, stat.replicas);
 *   }
 */
int lx_stat(const char* device_name, xdevice_stat_t* stat);

/* ========== 便利宏定义 ========== */

/* 检查返回值是否成功 */
#define XDEVICE_SUCCESS(ret) ((ret) >= 0)
#define XDEVICE_FAILED(ret)  ((ret) < 0)

/* 检查文件描述符是否有效 */
int lx_fd_valid(xdevice_fd_t fd);
#define XDEVICE_FD_VALID(fd) lx_fd_valid(fd)

/* POSIX兼容的定位常量 */
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1  
#define SEEK_END 2
#endif

/* ========== 高级便利API ========== */

/**
 * 读取整个设备内容到缓冲区
 * 
 * @param device_name 设备名称
 * @param buf 缓冲区指针的指针(函数内分配内存)
 * @param size 读取的字节数指针
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 注意: 调用者需要free(*buf)释放内存
 * 
 * 示例:
 *   char* data = NULL;
 *   size_t size;
 *   if (xdevice_read_all("config", (void**)&data, &size) == XDEVICE_OK) {
 *       printf("Config data: %.*s\n", (int)size, data);
 *       free(data);
 *   }
 */
int xdevice_read_all(const char* device_name, void** buf, size_t* size);

/**
 * 将缓冲区内容写入整个设备
 * 
 * @param device_name 设备名称
 * @param buf 数据缓冲区
 * @param size 数据大小
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   const char* config = "server_port=8080\nlog_level=INFO\n";
 *   xdevice_write_all("config", config, strlen(config));
 */
int xdevice_write_all(const char* device_name, const void* buf, size_t size);

/**
 * 从文件加载数据到设备
 * 
 * @param device_name 设备名称
 * @param file_path 本地文件路径
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   xdevice_load_from_file("database", "/tmp/backup.sql");
 */
int xdevice_load_from_file(const char* device_name, const char* file_path);

/**
 * 将设备数据保存到文件
 * 
 * @param device_name 设备名称
 * @param file_path 本地文件路径
 * @return XDEVICE_OK成功，负数表示错误码
 * 
 * 示例:
 *   xdevice_save_to_file("database", "/tmp/backup.sql");
 */
int xdevice_save_to_file(const char* device_name, const char* file_path);

/* ========== POSIX风格的便利宏 ========== */

/*
 * 这些宏提供了更接近POSIX风格的使用体验
 * 注意: 这些宏只是为了代码可读性，底层仍是XDevice API
 */

/* 文件操作宏 - 类似POSIX但使用逻辑设备名 */
#define xdev_open(name, flags, size)     xdevice_open(name, flags, size)
#define xdev_close(fd)                   xdevice_close(fd)
#define xdev_read(fd, buf, count)        xdevice_read(fd, buf, count)
#define xdev_write(fd, buf, count)       xdevice_write(fd, buf, count)
#define xdev_pread(fd, buf, count, off)  xdevice_pread(fd, buf, count, off)
#define xdev_pwrite(fd, buf, count, off) xdevice_pwrite(fd, buf, count, off)
#define xdev_lseek(fd, offset, whence)   xdevice_lseek(fd, offset, whence)
#define xdev_fsync(fd)                   xdevice_fsync(fd)
#define xdev_fstat(fd, stat)             xdevice_fstat(fd, stat)

/* 设备管理宏 */
#define xdev_unlink(name)                xdevice_unlink(name)
#define xdev_rename(old, new)            xdevice_rename(old, new)
#define xdev_exists(name)                xdevice_exists(name)
#define xdev_stat(name, stat)            xdevice_stat(name, stat)

#ifdef __cplusplus
}
#endif

#endif /* LIBXDEVICE_H */
